package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sky.constant.CacheConstants;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.entity.Category;
import com.sky.entity.Setmeal;
import com.sky.entity.SetmealDish;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.CategoryService;
import com.sky.service.SetmealDishService;
import com.sky.service.SetmealService;
import com.sky.vo.SetmealVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * TODO
 *
 * @Author Yjr
 * @Date 2025/5/21 9:54
 */
@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {
    @Autowired
    private SetmealDishService setmealDishService;

    /**
     * 新增套餐
     *
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addSetmeal(SetmealDTO dto) {
        if (dto==null){
            throw new RuntimeException("参数不合法");
        }
        Setmeal setmeal=new Setmeal();
        BeanUtils.copyProperties(dto,setmeal);
        boolean saveResult = this.save(setmeal);
        if (!saveResult){
            throw new RuntimeException("添加套餐失败");
        }
        if (!dto.getSetmealDishes().isEmpty()){
            List<SetmealDish> setmealDishes = dto.getSetmealDishes();
            setmealDishes.forEach(x->{
                x.setSetmealId(setmeal.getId());
                setmealDishService.save(x);
            });
        }
        deleteCache(dto.getCategoryId());
    }
    @Autowired
    private CategoryService categoryService;

    /**
     * 套餐分页条件查询
     *
     * @param dto
     * @return
     */
    @Override
    public PageResult pageSetmeal(SetmealPageQueryDTO dto) {

        Page<Setmeal> page=new Page<>(dto.getPage(),dto.getPageSize());
        this.lambdaQuery()
                .eq(dto.getCategoryId()!=null, Setmeal::getCategoryId,dto.getCategoryId())
                .like(StringUtils.hasLength(dto.getName()), Setmeal::getName,dto.getName())
                .eq(dto.getStatus()!=null, Setmeal::getStatus,dto.getStatus())
                .page(page);
        List<Setmeal> setmealList = page.getRecords();
        List<SetmealVO> setmealVOList = setmealList.stream().map(x -> {
            SetmealVO setmealVO = new SetmealVO();
            BeanUtils.copyProperties(x, setmealVO);
            Category category = categoryService.getById(x.getCategoryId());
            setmealVO.setCategoryName(category.getName());
            return setmealVO;
        }).collect(Collectors.toList());
        return new PageResult(page.getTotal(),setmealVOList);
    }

    /**
     * 删除套餐
     *
     * @param ids
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteSetmeal(List<Integer> ids) {
        List<Setmeal> setmeals = this.listByIds(ids);
        setmeals.stream().map(Setmeal::getCategoryId).distinct().forEach(this::deleteCache);
        this.removeBatchByIds(ids);
        setmealDishService.remove(Wrappers.<SetmealDish>lambdaQuery().in(SetmealDish::getSetmealId,ids));
    }


    /**
     * 根据id查询套餐详细信息
     *
     * @param id
     * @return
     */
    @Override
    public SetmealVO findById(Integer id) {
        Setmeal setmeal = this.getById(id);
        List<SetmealDish> setmealDishes = setmealDishService.lambdaQuery().eq(SetmealDish::getSetmealId, id).list();
        SetmealVO setmealVO=new SetmealVO();
        BeanUtils.copyProperties(setmeal, setmealVO);
        setmealVO.setSetmealDishes(setmealDishes);
        return setmealVO;
    }


    /**
     * 修改套餐
     *
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateSetmeal(SetmealDTO dto) {
        if (dto==null){
            throw new RuntimeException("参数不合法");
        }
        Setmeal setmeal=new Setmeal();
        BeanUtils.copyProperties(dto, setmeal);
        this.updateById(setmeal);
        setmealDishService.remove(Wrappers.<SetmealDish>lambdaQuery().eq(SetmealDish::getSetmealId,dto.getId()));
        if (!dto.getSetmealDishes().isEmpty()){
            List<SetmealDish> setmealDishes = dto.getSetmealDishes();
            setmealDishes.forEach(x->{
                x.setSetmealId(dto.getId());
                setmealDishService.save(x);
            });
        }
        deleteCache(this.getById(dto.getId()).getCategoryId());

    }

    /**
     * 修改套餐状态
     *
     * @param status
     * @param id
     */
    @Override
    public void updateSetmealStatus(Integer status, Long id) {
        if (status==null && id==null){
            throw new RuntimeException("参数异常");
        }
        Setmeal setmeal = Setmeal.builder().status(status).id(id).build();
        this.updateById(setmeal);
        deleteCache(this.getById(id).getCategoryId());
    }

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 根据分类套餐
     *
     * @param categoryId
     * @return
     */
    @Override
    public List<SetmealVO> findByCategoryId(Integer categoryId) {
        String setmealVOListJson = (String) stringRedisTemplate.opsForHash().get(CacheConstants.SETMEAL_CATEGORY_ID, categoryId.toString());

        if (!StringUtils.hasLength(setmealVOListJson)){
            List<Setmeal> setmeals = this.lambdaQuery()
                    .eq(Setmeal::getCategoryId, categoryId)
                    .eq(Setmeal::getStatus, 1)
                    .list();
            if (setmeals.isEmpty()){
                return null;
            }
            List<SetmealVO> setmealVOList = setmeals.stream().map(x -> {
                SetmealVO setmealVO = new SetmealVO();
                BeanUtils.copyProperties(x, setmealVO);
                return setmealVO;
            }).collect(Collectors.toList());
            stringRedisTemplate.opsForHash().put(CacheConstants.SETMEAL_CATEGORY_ID, categoryId.toString(), JSON.toJSONString(setmealVOList));
            return setmealVOList;
        }
        return JSON.parseArray(setmealVOListJson, SetmealVO.class);

    }

    /**
     * 删除缓存
     * @param categoryId
     */
    public void deleteCache(Long categoryId){
        stringRedisTemplate.opsForHash().delete(CacheConstants.SETMEAL_CATEGORY_ID, categoryId.toString());
    }
}
